home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
5_11.lha
/
5_11
/
tst.c
< prev
next >
Wrap
Text File
|
1993-08-08
|
5KB
|
307 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
include <stream.h>
include <string.h>
include <ctype.h>
include <error.h>
include "5_10a.h" // class table
include "5_10a1.c" // table::lock
include "5_10a2.c" // table::table()
include "5_10a3.c" // table::~table()
include "5_11A.h" // enum exprtype
include "5_11B.h" // struct tree
include "5_11C.h" // struct token
include "5_11D.h" // class expr
tatic token curr_tok;
include "5_11h.c" // forward declarations
tatic tree* term(istream& input, table *variables)
tree* left = prim(input, variables);
for (;;)
switch (curr_tok.type)
{
case MUL:
case DIV:
tree* head = new tree;
head->type = curr_tok.type;
head->left = left;
get_token(input, variables); // eat '*','/'
head->right = prim(input, variables);
left = head;
break;
default: // collapse node
return left;
}
ree *expandtree(istream &input, table *variables)
if (curr_tok.type == END)
{
tree *ret = new tree;
ret->type = NUMBER;
ret->value = 0;
return ret;
}
include "5_11c.c" // else get series of expressions
tatic tree* prim(istream& input, table *variables)
tree* ret = new tree;
switch (curr_tok.type)
{
case NUMBER:
ret->type = NUMBER;
ret->value = curr_tok.value;
get_token(input, variables); // skip number
return ret;
case MINUS:
ret->type = MINUS;
get_token(input, variables); // skip '-'
ret->left = prim(input, variables);
ret->right = 0;
return ret;
case LP:
ret->type = LP;
get_token(input, variables); // skip '('
ret->left = get_expr(input, variables);
if (curr_tok.type != RP)
{
error(") expected");
break;
}
get_token(input, variables); // skip ')'
return ret;
case END:
error("end of expression unexpected");
break;
include "5_11b.c" // case NAME
default:
error("prim: unknown type within tree, %c", curr_tok.type);
break;
}
// error case
ret->value = 0;
ret->type = NUMBER;
return ret;
xpr:: expr(char* s)
istream input(strlen(s), s);
evaluated = 0;
get_token(input, &variables);
head = expandtree(input, &variables);
tatic tree* get_expr(istream& input, table *variables)
tree* left = term(input, variables);
for (;;)
switch (curr_tok.type)
{
case PLUS:
case MINUS:
tree* head = new tree;
head->type = curr_tok.type;
head->left = left;
get_token(input, variables); // eat '+','-'
head->right = term(input, variables);
left = head;
break;
default: // collapse node
return left;
}
/ Evaluate the given expression tree
nt treeval(tree* head, table *variables)
if (head)
switch (head->type)
{
case PLUS:
return treeval(head->left, variables) +
treeval(head->right, variables);
case MINUS:
if (head->right)
return treeval(head->left, variables) -
treeval(head->right, variables);
else
return -treeval(head->left, variables);
case DIV:
int l = treeval(head->left, variables);
int r = treeval(head->right, variables);
if (r != 0)
return l / r;
else
return error("division by 0");
case MUL:
return treeval(head->left, variables) *
treeval(head->right, variables);
case NUMBER:
return head->value;
case LP:
return treeval(head->left, variables);
include "5_11e.c" // case ASSIGN, NAME
case RP:
case END:
error ("invalid type within treeval, '%c'", head->type);
break;
}
else
error("NULL node found");
return 0;
/ print out the tree in infix format
tatic void infixprint(tree* head)
cout << "( ";
if (head)
switch (head->type)
{
case PLUS:
case DIV:
case MUL:
infixprint (head->left);
cout << chr (head->type) << " ";
infixprint (head->right);
break;
case MINUS:
if (head->right)
{
infixprint (head->left);
cout << "- ";
infixprint (head->right);
}
else
{
cout << "- ";
infixprint (head->left);
}
break;
case NUMBER:
cout << head->value;
break;
case LP:
infixprint (head->left);
break;
include "5_11i.c"
case RP:
case SEMICOLON:
case END:
error ("invalid type within infixprint, '%c'", head->type);
break;
}
else
error ("NULL node found");
cout << " ) ";
include "5_11d.c" // expr::eval()
tatic void get_token(istream &input, table *variables)
char ch;
do { // skip whitespace
if (!input.get(ch))
{ curr_tok.type = END; return; }
} while (isspace(ch));
switch (ch)
{
include "5_11g.c"
curr_tok.type = ch;
return;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
input.putback(ch);
input >> curr_tok.value;
curr_tok.type = NUMBER;
return;
include "5_11a.c" // isalpha()
error("bad token, ch='%c'", ch);
curr_tok.type = END;
return;
}
include "5_11f.c" // expr::print()
har *strs[] =
"",
"1 ",
"2*3 ",
"2-3 ",
"5/2",
"123/4+123*4-3",
"a=5/2; 57+a-3 ",
0
;
oid lookat(char *s)
cout << "x = '" << s << "'\n";
expr x(s);
cout << "x = "; x.print(); cout << "\n";
cout << "x = " << x.eval() << "\n";
cout << "\n";
ain(int argc, char **argv)
if (argc > 1)
while (*++argv)
lookat(*argv);
else
for (int i = 0; strs[i]; i++)
lookat(strs[i]);
return 0;